Some Assembly Required 2
Writeup(未完)t6o_o6t.icon
未完のWriteupとはt6o_o6t.icon
argsと命名したものが本当にargsのような意味なのかは分からない
定数の配列だと思う
fは、受け取った数値から0xc3(=195)を引いてindexとして、argsの特定要素を参照して返す
code:reverse_1.js
const args = 'copy_char', 'value', '207aLjBod', '1301420SaUSqf', '233ZRpipt', '2224QffgXU', 'check_flag', '408533hsoVYx', 'instance', '278338GVFUrH', 'Correct!', '549933ZVjkwI', 'innerHTML', 'charCodeAt', './aD8SvhyVkb', 'result', '977AzKzwq', 'Incorrect!', 'exports', 'length', 'getElementById', '1jIrMBu', 'input', '615361geljRK'; const f = function(arg1, arg2) {
arg1 = arg1 - 0xc3;
return val;
};
(function(str, expected) {
const f2 = f;
while (!![]) {
try {
const f2result = -parseInt(f2(0xc8)) * -parseInt(f2(0xc9)) + -parseInt(f2(0xcd)) + parseInt(f2(0xcf)) + parseInt(f2(0xc3)) + -parseInt(f2(0xc6)) * parseInt(f2(0xd4)) + parseInt(f2(0xcb)) + -parseInt(f2(0xd9)) * parseInt(f2(0xc7));
if (f2result === expected)
break;
else
} catch (e) {
}
}
}(args, 0x4bb06));
let exports;
(async()=>{
const f2 = f;
let fetchresult = await fetch(f2(0xd2))
}
)();
function onButtonPress() {
const f2 = f;
for (let i = 0x0; i < documentpart'length'; i++) { }
}
argsの値は、parseIntに渡される値がNaNになる限り後ろから前へ周り続けそうt6o_o6t.icon 即時関数をローカルで実行してみて、strの値を見たt6o_o6t.icon code:str.js
[
'615361geljRK', 'copy_char',
'value', '207aLjBod',
'1301420SaUSqf', '233ZRpipt',
'2224QffgXU', 'check_flag',
'408533hsoVYx', 'instance',
'278338GVFUrH', 'Correct!',
'549933ZVjkwI', 'innerHTML',
'charCodeAt', './aD8SvhyVkb',
'result', '977AzKzwq',
'Incorrect!', 'exports',
'length', 'getElementById',
'1jIrMBu', 'input'
]
この状態で、onButtonPressやasyncに渡される値がどれかを見る必要がある
asyncの即時関数は、wasmファイルをfetchしている
このなかでcheck_flag
code:reverse_2.js
const args = 'copy_char', 'value', '207aLjBod', '1301420SaUSqf', '233ZRpipt', '2224QffgXU', 'check_flag', '408533hsoVYx', 'instance', '278338GVFUrH', 'Correct!', '549933ZVjkwI', 'innerHTML', 'charCodeAt', './aD8SvhyVkb', 'result', '977AzKzwq', 'Incorrect!', 'exports', 'length', 'getElementById', '1jIrMBu', 'input', '615361geljRK'; const f = function(arg1, arg2) {
arg1 = arg1 - 0xc3;
return val;
};
(function(str, expected) {
const f2 = f;
while (!![]) {
try {
const f2result = -parseInt(f2(0xc8)) * -parseInt(f2(0xc9)) + -parseInt(f2(0xcd)) + parseInt(f2(0xcf)) + parseInt(f2(0xc3)) + -parseInt(f2(0xc6)) * parseInt(f2(0xd4)) + parseInt(f2(0xcb)) + -parseInt(f2(0xd9)) * parseInt(f2(0xc7));
if (f2result === expected)
break;
else
} catch (e) {
}
}
}(args, 0x4bb06));
let exports;
(async()=>{
const f2 = f;
let fetchresult = await fetch('./aD8SvhyVkb')
// wasmの関数をexportsから呼び出せるようにする?
}
)();
function onButtonPress() {
const f2 = f;
let input = document.getElementById('input').value;
for (let i = 0; i < input.length; i++) {
exports.copy_char(input.charCodeAt(i), i);
// i 文字目に
}
exports.copy_char(0, input.length),
exports.check_flag() == 1 ? document.getElementById('result').innerHTML = 'Correct!' : document.getElementById('result').innerHTML = 'Incorrect!';
}
読めた!!t6o_o6t.icon
copy_charはただcopyしているだけだと思う
check_flagで1が返るようにしたい
wasmを読む必要がある?
code:out.js
export memory memory(initial: 2, max: 0);
global g_a:int = 66864;
export global input:int = 1072;
export global dso_handle:int = 1024;
export global data_end:int = 1328;
export global global_base:int = 1024;
export global heap_base:int = 66864;
export global memory_base:int = 0;
export global table_base:int = 1;
table T_a:funcref(min: 1, max: 1);
data d_xakgKNsmi11991nkjlii1j0nmm09(offset: 1024) =
"xakgK\Ns><m:i1>1991:nkjl<ii1j0n=mm09;<i:u\00\00";
export function wasm_call_ctors() {
}
export function strcmp(a:int, b:int):int {
var c:int = g_a;
var d:int = 32;
var e:int = c - d;
loop L_b {
var h:ubyte_ptr = e4:int; var i:int = 1;
var j:int = h + i;
var l:ubyte_ptr = e3:int; var m:int = 1;
var n:int = l + m;
var q:int = 255;
var r:int = p & q;
if (r) goto B_c;
var t:int = 255;
var u:int = s & t;
var w:int = 255;
var x:int = v & w;
var y:int = u - x;
goto B_a;
label B_c:
var aa:int = 255;
var ba:int = z & aa;
var da:int = 255;
var ea:int = ca & da;
var fa:int = ba;
var ga:int = ea;
var ha:int = fa == ga;
var ia:int = 1;
var ja:int = ha & ia;
if (ja) continue L_b;
}
var la:int = 255;
var ma:int = ka & la;
var oa:int = 255;
var pa:int = na & oa;
var qa:int = ma - pa;
label B_a:
return ra;
}
export function check_flag():int {
var a:int = 0;
var b:int = 1072;
var c:int = 1024;
var d:int = strcmp(c, b);
var e:int = d;
var f:int = a;
var g:int = e != f;
var h:int = -1;
var i:int = g ^ h;
var j:int = 1;
var k:int = i & j;
return k;
}
function copy(a:int, b:int) {
var c:int = g_a;
var d:int = 16;
var e:int_ptr = c - d;
if (eqz(f)) goto B_a;
var h:int = 8;
var i:int = g ^ h;
label B_a:
}
読め無さそうt6o_o6t.icon
読めないと思い込んでいたt6o_o6t.icon
check_flagを1にできればよいので、check_flagの内容を把握できれば良い
b = 1024というのは、strcmpにbが渡されていることから、文字列のアドレス